import axios from 'axios'
import { message } from 'ant-design-vue'
import { cloneDeep } from 'lodash-es'
import { getEnvData } from '@/utils/tools'
import config from '@/config'

// 引入并发拦截器
import ConcurrentInterceptors from './concurrentInterceptors'
// 创建并发实例对象,并设置最大并发数量
const concurrent = new ConcurrentInterceptors(config.maxProgressCount)

// 创建实例
const instance = axios.create({
  baseURL: getEnvData('VITE_API_BASEURL'),
  timeout: 10000
})

// 请求之前拦截
instance.interceptors.request.use(
  async config => {
    await concurrent.interceptors()
    return config
  },
  err => {
    return Promise.reject(err)
  }
)

// 响应后拦截
instance.interceptors.response.use(
  res => {
    concurrent.next()
    if (res.status !== 200) {
      return Promise.reject(res)
    }
    // 假设code == 1时为正常
    if (res.data.code == 1) {
      return res
    } else {
      let msg = res.data.msg || '接口code数据返回异常，请联系管理员！'
      message.warning(msg)
      return Promise.reject(res)
    }
  },
  err => {
    concurrent.next()
    if (err && err.response && err.response.status) {
      switch (err.response.status) {
        case 400:
        case 401:
        case 404:
        case 500:
          message.warning(`请求地址：${err.config.url}失败，状态码：${err.response.status}，请联系管理员!`)
          break
      }
      return Promise.reject(err)
    } else if (err.code === 'ERR_CANCELED') {
      // 取消了网络请求
      return Promise.reject(err)
    } else {
      return Promise.reject(err)
    }
  }
)

interface anyObject {
  [attr: string]: any
}

/**
 * GET请求的封装
 * @param url
 * @param params
 * @param config  其他配置项，比如headers、signal 等等
 * @return Promise
 */
export function get(url: string, params = {}, config: anyObject = {}) {
  let instanceConfig: anyObject = {}

  // 处理signal取消请求实例
  if (config.hasOwnProperty('controller')) {
    config.controller = new AbortController()
    instanceConfig = cloneDeep(config)
    delete instanceConfig.controller
    instanceConfig.signal = config.controller.signal
  }

  return instance({
    url: url,
    method: 'get',
    params: params,
    ...instanceConfig
  })
    .then(res => {
      return Promise.resolve(res.data)
    })
    .catch(err => {
      return Promise.reject(err)
    })
}

/**
 * POST请求的封装
 * @param url
 * @param params
 * @param config  其他配置项，比如headers、signal 等等
 * @return Promise
 */
export function post(url: string, params = {}, config: anyObject = {}) {
  let instanceConfig: anyObject = {}

  // 处理signal取消请求实例
  if (config.hasOwnProperty('controller')) {
    config.controller = new AbortController()
    instanceConfig = cloneDeep(config)
    delete instanceConfig.controller
    instanceConfig.signal = config.controller.signal
  }

  return instance({
    url: url,
    method: 'post',
    data: params,
    ...instanceConfig
  })
    .then(res => {
      return Promise.resolve(res.data)
    })
    .catch(err => {
      return Promise.reject(err)
    })
}

//7、post请求封装---下载excel文件流专用
//   export function postExcel(url, params = {}, headers = { 'Content-Type': 'application/json' }) {
//     return new Promise((resolve, reject) => {
//       instance({
//         url: url,
//         method: 'post',
//         data: params,
//         headers: headers,
//         responseType: 'arraybuffer'
//       }).then(res => {
//         let errData = undefined
//         try {
//           let enc = new TextDecoder('utf-8')
//           errData = JSON.parse(enc.decode(new Uint8Array(res.data)))
//         } catch (err) { }
//         if (errData) {
//         //   Vue.prototype.$antMessage.warn(errData.message);
//           reject(errData);
//         } else {
//           resolve(res.data);
//         }
//         // resolve()
//       }).catch(err => {
//         reject(err);
//       })
//     })
//   }
